package com.brzjomo.secretiveworld.object.item;

import java.util.List;
import java.util.Random;

import com.brzjomo.secretiveworld.init.ModDamageSource;
import com.brzjomo.secretiveworld.init.ModItems;
import com.brzjomo.secretiveworld.util.helper.RandomNumberHelper;
import com.google.common.collect.Multimap;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.material.Material;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.IItemTier;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.TieredItem;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;

public class SacrificialKnifeItem extends TieredItem {
	private final float attackDamage;
	private final float attackSpeed;

	public SacrificialKnifeItem(IItemTier tierIn, float attackDamageIn, float attackSpeedIn, Properties builder) {
		super(tierIn, builder);
		this.attackSpeed = attackSpeedIn;
		this.attackDamage = attackDamageIn + tierIn.getAttackDamage();
	}

	public float getAttackDamage() {
		return this.attackDamage;
	}

	public boolean canPlayerBreakBlockWhileHolding(BlockState state, World worldIn, BlockPos pos, PlayerEntity player) {
		return !player.isCreative();
	}

	public float getDestroySpeed(ItemStack stack, BlockState state) {
		Block block = state.getBlock();
		if (block == Blocks.COBWEB) {
			return 10.0F;
		} else {
			Material material = state.getMaterial();
			return material != Material.PLANTS && material != Material.TALL_PLANTS && material != Material.CORAL
					&& !state.isIn(BlockTags.LEAVES) && material != Material.GOURD ? 0.5F : 1.0F;
		}
	}

	public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) {
		stack.damageItem(1, attacker, (p_220045_0_) -> {
			p_220045_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
		});
		return true;
	}

	public boolean onBlockDestroyed(ItemStack stack, World worldIn, BlockState state, BlockPos pos,
			LivingEntity entityLiving) {
		if (state.getBlockHardness(worldIn, pos) != 0.0F) {
			stack.damageItem(2, entityLiving, (p_220044_0_) -> {
				p_220044_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
			});
		}

		return true;
	}

	public boolean canHarvestBlock(BlockState blockIn) {
		return blockIn.getBlock() == Blocks.COBWEB;
	}

	@SuppressWarnings("deprecation")
	public Multimap<String, AttributeModifier> getAttributeModifiers(EquipmentSlotType equipmentSlot) {
		Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(equipmentSlot);
		if (equipmentSlot == EquipmentSlotType.MAINHAND) {
			multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER,
					"Weapon modifier", (double) this.attackDamage, AttributeModifier.Operation.ADDITION));
			multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER,
					"Weapon modifier", (double) this.attackSpeed, AttributeModifier.Operation.ADDITION));
		}

		return multimap;
	}

	// 增加物品提示
	@Override
	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
		tooltip.add(new TranslationTextComponent("tooltip.secretiveworld.sacrificial_knife_item_1")
				.applyTextStyle(TextFormatting.ITALIC).applyTextStyle(TextFormatting.AQUA));
		tooltip.add(new TranslationTextComponent("tooltip.secretiveworld.sacrificial_knife_item_2")
				.applyTextStyle(TextFormatting.ITALIC).applyTextStyle(TextFormatting.AQUA));
		super.addInformation(stack, worldIn, tooltip, flagIn);
	}

	@Override
	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
		Random rand = new Random();
		ItemStack itemstack = playerIn.getHeldItem(handIn);
		ItemStack mithrilKnife = new ItemStack(ModItems.MITHRIL_SACRIFICIAL_KNIFE.get());
		ItemStack diamondKnife = new ItemStack(ModItems.DIAMOND_SACRIFICIAL_KNIFE.get());
		ItemStack goldKnife = new ItemStack(ModItems.GOLD_SACRIFICIAL_KNIFE.get());
		ItemStack silverKnife = new ItemStack(ModItems.SILVER_SACRIFICIAL_KNIFE.get());
		ItemStack ironKnife = new ItemStack(ModItems.IRON_SACRIFICIAL_KNIFE.get());
		ItemStack copperKnife = new ItemStack(ModItems.COPPER_SACRIFICIAL_KNIFE.get());
		ItemStack stoneKnife = new ItemStack(ModItems.STONE_SACRIFICIAL_KNIFE.get());
		ItemStack woodenKnife = new ItemStack(ModItems.WOODEN_SACRIFICIAL_KNIFE.get());
		Boolean isRank4 = ItemStack.areItemsEqual(itemstack, mithrilKnife)
				|| ItemStack.areItemsEqual(itemstack, diamondKnife);
		Boolean isRank3 = ItemStack.areItemsEqual(itemstack, goldKnife)
				|| ItemStack.areItemsEqual(itemstack, silverKnife);
		Boolean isRank2 = ItemStack.areItemsEqual(itemstack, ironKnife)
				|| ItemStack.areItemsEqual(itemstack, copperKnife);
		Boolean isRank1 = ItemStack.areItemsEqual(itemstack, stoneKnife)
				|| ItemStack.areItemsEqual(itemstack, woodenKnife);
		Boolean flag = false;
		int prob1 = 3;
		int prob2 = 7;

		if (itemstack.isItemEqual(mithrilKnife)) {
			prob1 = prob1 - 2;// 1
			prob2 = prob2 - 4;// 3
		} else if (itemstack.isItemEqual(diamondKnife)) {
			prob1 = prob1 - 1;// 2
			prob2 = prob2 - 5;// 2
		} else if (itemstack.isItemEqual(goldKnife)) {
			prob1 = prob1 - 0;// 3
			prob2 = prob2 - 4;// 3
		} else if (itemstack.isItemEqual(silverKnife)) {
			prob1 = prob1 - 1;// 2
			prob2 = prob2 - 4;// 3
		} else if (itemstack.isItemEqual(ironKnife)) {
			prob1 = prob1 + 1;// 4
			prob2 = prob2 - 5;// 2
		} else if (itemstack.isItemEqual(copperKnife)) {
			prob1 = prob1 + 1;// 4
			prob2 = prob2 - 5;// 2
		} else if (itemstack.isItemEqual(stoneKnife)) {
			prob1 = prob1 + 2;// 5
			prob2 = prob2 - 4;// 3
		} else if (itemstack.isItemEqual(woodenKnife)) {
			prob1 = prob1 + 3;// 6
			prob2 = prob2 - 4;// 3
		}

		// cause damage
		if (rand.nextInt(10) < prob1) {
			playerIn.attackEntityFrom(ModDamageSource.SACRIFICE, 1000);
		} else if (RandomNumberHelper.randIntBetween(prob1, 10) < prob1 + prob2) {
			playerIn.attackEntityFrom(ModDamageSource.SACRIFICE, 14);
		} else {
			playerIn.attackEntityFrom(ModDamageSource.SACRIFICE, 8);
		}

		// skin player head
		CompoundNBT compoundnbt = new CompoundNBT();
		ItemStack playerHead = new ItemStack(Items.PLAYER_HEAD);
		String[] list = playerIn.getName().toString().split("'");
		compoundnbt.putString("SkullOwner", list[1]);
		playerHead.setTag(compoundnbt);

		// drop items
		if (playerIn.getHealth() == 0) {
			if (isRank4) {
				if (rand.nextInt(10) == 0) {// 10%
					playerIn.dropItem(new ItemStack(Items.ZOMBIE_HEAD, 1), true, false);
				} else if (rand.nextInt(20) == 0) {// 5%
					flag = true;
					playerIn.dropItem(playerHead, true, false);
				}
			} else if (isRank3) {
				if (rand.nextInt(20) == 0) {// 5%
					playerIn.dropItem(new ItemStack(Items.ZOMBIE_HEAD, 1), true, false);
				} else if (rand.nextInt(40) == 0) {// 2.5%
					flag = true;
					playerIn.dropItem(playerHead, true, false);
				}
			} else if (isRank2) {
				if (rand.nextInt(40) == 0) {// 2.5%
					playerIn.dropItem(new ItemStack(Items.ZOMBIE_HEAD, 1), true, false);
				} else if (rand.nextInt(200) == 0) {// 0.5%
					flag = true;
					playerIn.dropItem(playerHead, true, false);
				}
			} else if (isRank1) {
				if (rand.nextInt(100) == 0) {// 1%
					playerIn.dropItem(new ItemStack(Items.ZOMBIE_HEAD, 1), true, false);
				} else if (rand.nextInt(2000) == 0) {// 0.05%
					flag = true;
					playerIn.dropItem(playerHead, true, false);
				}
			}
		} else {
			if (isRank4) {
				if (rand.nextInt(100) < 25) {// 40%
					if (rand.nextInt(2) == 0) {
						flag = true;
					}
					// 虔诚之血
					playerIn.dropItem(new ItemStack(Items.BEDROCK, 1), true, false);
				} else {
					// 鲜血
					playerIn.dropItem(new ItemStack(Items.APPLE, 1), true, false);
				}
			} else if (isRank3) {
				if (rand.nextInt(100) < 30) {// 30%
					if (rand.nextInt(2) == 0) {
						flag = true;
					}
					// 虔诚之血
					playerIn.dropItem(new ItemStack(Items.BEDROCK, 1), true, false);
				} else {
					// 鲜血
					playerIn.dropItem(new ItemStack(Items.APPLE, 1), true, false);
				}
			} else if (isRank2) {
				if (rand.nextInt(100) < 20) {// 20%
					if (rand.nextInt(2) == 0) {
						flag = true;
					}
					// 虔诚之血
					playerIn.dropItem(new ItemStack(Items.BEDROCK, 1), true, false);
				} else {
					// 鲜血
					playerIn.dropItem(new ItemStack(Items.APPLE, 1), true, false);
				}
			} else if (isRank1) {
				if (rand.nextInt(100) < 10) {// 10%
					if (rand.nextInt(2) == 0) {
						flag = true;
					}
					// 虔诚之血
					playerIn.dropItem(new ItemStack(Items.BEDROCK, 1), true, false);
				} else {
					// 鲜血
					playerIn.dropItem(new ItemStack(Items.APPLE, 1), true, false);
				}
			}
		}

		// give enhancement
		if (playerIn.getHealth() != 0 && !worldIn.isRemote) {
			if (rand.nextInt(99) > 98) {
				playerIn.addPotionEffect(new EffectInstance(Effects.LUCK, 600, 2));
				playerIn.sendMessage(
						new TranslationTextComponent("tooltip.secretiveworld.sacrificial_knife_item_tip_1", 0));
			} else if (rand.nextInt(99) > 97) {
				playerIn.addPotionEffect(new EffectInstance(Effects.LUCK, 600, 1));
			} else if (rand.nextInt(99) > 95) {
				playerIn.addPotionEffect(new EffectInstance(Effects.LUCK, 600, 0));
			} else if (rand.nextInt(99) > 92) {
				playerIn.addPotionEffect(new EffectInstance(Effects.ABSORPTION, 600, 2));
			} else if (rand.nextInt(99) > 86) {
				playerIn.addPotionEffect(new EffectInstance(Effects.ABSORPTION, 600, 1));
			} else if (rand.nextInt(99) > 81) {
				playerIn.addPotionEffect(new EffectInstance(Effects.ABSORPTION, 600, 0));
			} else if (rand.nextInt(99) > 78) {
				playerIn.addPotionEffect(new EffectInstance(Effects.FIRE_RESISTANCE, 600, 1));
			} else if (rand.nextInt(99) > 73) {
				playerIn.addPotionEffect(new EffectInstance(Effects.FIRE_RESISTANCE, 600, 0));
			} else if (rand.nextInt(99) > 68) {
				playerIn.addPotionEffect(new EffectInstance(Effects.LEVITATION, 320, 0));
			} else if (rand.nextInt(99) > 65) {
				playerIn.addPotionEffect(new EffectInstance(Effects.BAD_OMEN, 1200, 0));
			} else if (rand.nextInt(99) > 60) {
				playerIn.addPotionEffect(new EffectInstance(Effects.GLOWING, 200, 0));
			} else if (rand.nextInt(99) > 52) {
				playerIn.addPotionEffect(new EffectInstance(Effects.BLINDNESS, 1000, 0));
			} else if (rand.nextInt(99) > 45) {
				playerIn.addPotionEffect(new EffectInstance(Effects.NAUSEA, 240, 0));
			} else if (rand.nextInt(99) > 30) {
				playerIn.addPotionEffect(new EffectInstance(Effects.MINING_FATIGUE, 1200, 2));
			} else if (rand.nextInt(99) > 20) {
				playerIn.addPotionEffect(new EffectInstance(Effects.SLOWNESS, 1000, 0));
			} else if (rand.nextInt(99) > 10) {
				playerIn.addPotionEffect(new EffectInstance(Effects.WEAKNESS, 1000, 1));
			} else {
				playerIn.addPotionEffect(new EffectInstance(Effects.UNLUCK, 1200, 0));
			}
		}

		// damage item
		itemstack.damageItem(1, playerIn, (p_220045_0_) -> {
			p_220045_0_.sendBreakAnimation(EquipmentSlotType.MAINHAND);
		});
		if (!worldIn.isRemote) {
			if (flag) {
				if (rand.nextInt(4) < 1) {
					TranslationTextComponent textOnUse2 = new TranslationTextComponent(
							"tooltip.secretiveworld.sacrificial_knife_item_onuse_2");
					playerIn.sendMessage(textOnUse2);
				} else {
					TranslationTextComponent textOnUse1 = new TranslationTextComponent(
							"tooltip.secretiveworld.sacrificial_knife_item_onuse_1");
					playerIn.sendMessage(textOnUse1);
				}
				flag = false;
			}
			this.playUseSound(worldIn, playerIn.getPosition());
		}
		return ActionResult.resultSuccess(itemstack);
	}

	private void playUseSound(World worldIn, BlockPos pos) {
		worldIn.playSound((PlayerEntity) null, pos, SoundEvents.ENTITY_PLAYER_HURT, SoundCategory.PLAYERS, 1.0F,
				(random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F);
	}

}
